package com.iussoft.receiveData.interceptor;

import com.alibaba.fastjson.JSON;
import com.apache.exception.BusinessException;
import com.apache.tools.DateUtils;
import com.apache.tools.StrUtil;
import com.apache.tools.UUIDUtil;
import com.iussoft.tools.*;
import org.apache.commons.io.Charsets;
import org.apache.commons.io.IOUtils;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
import java.util.Map;

/**
 * description: 自定义查询拦截器
 *
 * @author dyh 创建时间：2020年02月29日
 */
@SpringHandlerInterceptor(includePatterns = {"/data/**","/receive/data/**","/receive/file/data/**","/file/data/**"})
public class SearchInterceptor extends SuperInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        long startTime = System.currentTimeMillis();
        String traceId = getTraceId(request);
        String messages = null;
        String url = request.getRequestURI();
        request.setAttribute("traceId",traceId);
        try {
            RequestMessage reqMsg = new RequestMessage();
            reqMsg.setTimestamp(startTime);
            boolean mark = authorityCertification(request,reqMsg);//验证权限
            if(!mark){
                throw new BusinessException(UnityErrorCode.CHECK_ACT_DATA.getDesc());
            }
            if(url.indexOf("/file/data/") !=-1){//文件上传
                return true;
            }
            //获取请求报文
            messages = IOUtils.toString(request.getInputStream(), "UTF-8");
            reqMsg.setUrlMap(getRequestParamMap(request));
            if (StrUtil.isNull(messages) && reqMsg.getUrlMap().isEmpty()) {//参数为空
                throw new BusinessException(UnityErrorCode.REQ_NULL_JSON.getDesc());
            }
            Enumeration<String> headerNames = request.getHeaderNames();
            //获取获取的消息头名称，获取对应的值，并输出
            while(headerNames.hasMoreElements()){
                String nextElement = headerNames.nextElement();
                reqMsg.setHeadMap(nextElement,request.getHeader(nextElement));
            }
            //转换请求报文
            reqMsg = this.getRequestMessage(request, messages, reqMsg);
            request.setAttribute("requestCode", reqMsg.getRequestCode());
            request.setAttribute("RequestMessage", reqMsg);
        } catch (BusinessException e) {
            String total = (System.currentTimeMillis()-startTime)+"";
            LoggerUtil.warnSource("exception = {}; infoType = exception; traceId = {}; requestUrl = {}; requestTime = {}; errorMessage = {}; requestIp = {}; exeSys = receive; total = {}; level = {}",e.getClass().getSimpleName(), traceId, url,DateUtils.Now.fmt_yyyyMMdd_HHmmss(), e.getMessage(),getRequestIp(request),total,"ERROR");
            buildResponseMsg(request, UnityErrorCode.JSON_PROSSES.getValue(), e.getMessage(), "");
            postHandle(request, response, handler, null);
            return false;
        } catch (Exception e) {
            String total = (System.currentTimeMillis()-startTime)+"";
            String mesg = UnityErrorCode.JSON_PROSSES.getDesc()+"[message="+e.getMessage()+"]";
            LoggerUtil.warnSource("exception = {}; infoType = exception; traceId = {}; requestUrl = {}; requestTime = {}; errorMessage = {}; requestIp = {}; exeSys = receive; total = {}; level = {}",e.getClass().getSimpleName(), traceId,url,DateUtils.Now.fmt_yyyyMMdd_HHmmss(), mesg,getRequestIp(request),total,"ERROR");
            buildResponseMsg(request, UnityErrorCode.JSON_PROSSES.getValue(), UnityErrorCode.JSON_PROSSES.getDesc(), "");
            postHandle(request, response, handler, null);
            return false;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o,
                           ModelAndView modelAndView) throws Exception {

        Map<String, Object> datas = (Map) request.getAttribute(RESPONSE_MSG);
        response.setContentType(request.getContentType());
        datas = buildDataMap(datas, request);

        String data = null;
        if(datas.containsKey("entity")){
            data = JSON.toJSONString(datas.get("entity")).replaceAll("\n","").replaceAll("\r","").replaceAll(";","；");
        } else {
            data = JSON.toJSONString(datas);
        }

        RequestMessage reqMsg = (RequestMessage) request.getAttribute("RequestMessage");
        String traceId = getTraceId(request);
        String userIp = getRequestIp(request);
        String url = request.getRequestURI();
        if(null != reqMsg) {
            String reqTime = DateUtils.longToStr(reqMsg.getTimestamp(), DateUtils.FmtStr.yyyyMMdd_HHmmss);//开始时间
            String interfaceCode = StrUtil.doNull(reqMsg.getInfoByKey("fromInterfaceCode"),reqMsg.getInfoByKey("requestCode"));
            String sourceMsg = StrUtil.doNull(reqMsg.getSourceMsg(),JSON.toJSONString(reqMsg.getUrlMap())).replaceAll("\n","").replaceAll("\r","").replaceAll(";","；");
            String total = (System.currentTimeMillis()-reqMsg.getTimestamp())+"";
            if(UnityErrorCode.SUCCESSFUL.getValue().equals(datas.get("errorCode"))){
                LoggerUtil.warnSource("traceId = {}; infoType = info; exeSys = receive; requestUrl = {}; requestTime = {}; interfaceCode = {}; total = {}; requestIp = {}; requestBody = {}; responseBody = {}", traceId, url, reqTime, interfaceCode,total, userIp,sourceMsg, data);
                LoggerUtil.errorSource("receive_reqId = {}; receive_requestTime = {}; receive_interfaceCode = {}; receive_time_long = {}", traceId, reqTime, interfaceCode,total);
            } else {
                boolean isEntity = datas.containsKey("entity");
                String msg = isEntity?data:String.valueOf(datas.get("errorMessage"));
                LoggerUtil.warnSource("traceId = {}; infoType = warning; exeSys = receive; requestUrl = {}; requestTime = {}; interfaceCode = {}; total = {}; requestIp = {}; requestBody = {}; errorMessage = {}", traceId, url, reqTime, interfaceCode,total, userIp,sourceMsg, msg);
            }
            if (StrUtil.isNotNull(reqMsg.getInfoByKey("requestPwd"))) {
                data = AesUtil.getInstance().encryptEcbMode(data, reqMsg.getInfoByKey("requestPwd"));
            }
        }
        //记录响应报文
        ServletOutputStream os = response.getOutputStream();
        os.write(data.getBytes(Charsets.UTF_8));
        os.close();
    }

}
